---
title: Widgets
description: Comprehensive guide to specialized content widgets for rich chat experiences
---

Widgets are specialized components for displaying and interacting with rich content in chat messages. They provide functionality beyond simple text, enabling multimedia, interactive elements, and custom parts.

This section describes how to use them standalone.

## ChatUI Widgets

## Markdown

Renders rich text with LaTeX math support, syntax highlighting, and citations.

```tsx
import { Markdown } from '@llamaindex/chat-ui/widgets'

function RichText({ content }) {
  return <Markdown>{content}</Markdown>
}
```

**Features:**

- **LaTeX Math** - Inline and block math rendering with KaTeX
- **Code Highlighting** - Syntax highlighting with highlight.js
- **Citations** - Clickable citation links
- **Custom Renderers** - Extensible rendering pipeline

**Example Content:**

````markdown
# Mathematical Formula

The quadratic formula is: $x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$

## Code Example

```python
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
```

### CodeBlock

Displays syntax-highlighted code with copy functionality.

```tsx
import { CodeBlock } from '@llamaindex/chat-ui/widgets'

function CodeDisplay({ code, language, filename }) {
  return (
    <CodeBlock
      code={code}
      language={language}
      filename={filename}
      showLineNumbers={true}
    />
  )
}
```
````

**Props:**

- `code` - Source code string
- `language` - Programming language for highlighting
- `filename` - Optional filename display
- `showLineNumbers` - Show/hide line numbers

### CodeEditor

Interactive code editor with multiple language support.

```tsx
import { CodeEditor } from '@llamaindex/chat-ui/widgets'

function InteractiveCode({ initialCode, language, onChange }) {
  return (
    <CodeEditor
      value={initialCode}
      language={language}
      onChange={onChange}
      theme="dark"
      extensions={['search', 'fold']}
    />
  )
}
```

**Supported Languages:**

- JavaScript/TypeScript
- Python
- CSS/SCSS
- HTML
- JSON
- Markdown

**Features:**

- **Syntax Highlighting** - Real-time highlighting
- **Auto-completion** - Language-aware suggestions
- **Code Folding** - Collapse code blocks
- **Search & Replace** - Built-in search functionality
- **Multiple Themes** - Light and dark themes

### DocumentEditor

Rich text document editor with markdown support. Please import editor styles from `@llamaindex/chat-ui/styles/editor.css` to ensure proper styling.

```tsx
import { DocumentEditor } from '@llamaindex/chat-ui/widgets'
import '@llamaindex/chat-ui/styles/editor.css'

function DocumentEdit({ content, onChange, title }) {
  return (
    <DocumentEditor
      content={content}
      onChange={onChange}
      className="custom-css-class"
    />
  )
}
```

**Note:** When using Next.js App Router, you need to dynamically import this component to avoid SSR issues:

```tsx
'use client'

import dynamic from 'next/dynamic'
import '@llamaindex/chat-ui/styles/editor.css'

const DocumentEditor = dynamic(
  () => import('@llamaindex/chat-ui/widgets').then(mod => mod.DocumentEditor),
  { ssr: false }
)

export default function Home() {
  return (
    <DocumentEditor content={"# Hello World"} onChange={console.log} />
  )
}
```

**Features:**

- **WYSIWYG Editing** - Visual editing with markdown output
- **Formatting Tools** - Bold, italic, lists, headers
- **Link Support** - Insert and edit links
- **Image Support** - Embed images
- **Live Preview** - Real-time markdown preview

### ChatFile

Displays a file attachment like image, pdf, etc.

```tsx
import { ChatFile } from '@llamaindex/chat-ui/widgets'

function FileDisplay() {
  return (
    <ChatFile
      file={{
        filename: 'upload.pdf',
        mediaType: 'application/pdf',
        url: 'https://pdfobject.com/pdf/sample.pdf',
      }}
    />
  )
}
```

### ChatSources

Displays source citations with document grouping.

```tsx
import { ChatSources } from '@llamaindex/chat-ui/widgets'

function SourceDisplay() {
  return (
    <ChatSources
      data={{
        nodes: [
          {
            id: '1',
            url: '/documents/paper.pdf',
            metadata: {
              title: 'Research Paper',
              page_number: 5,
            },
          },
        ],
      }}
    />
  )
}
```

**Features:**

- **Document Grouping** - Groups citations by document
- **Page Numbers** - Shows specific page references
- **Click to View** - Opens source documents
- **Metadata Display** - Shows title, author, date

### ChatEvent

Displays collapsible process event with status updates.

```tsx
import { ChatEvent } from '@llamaindex/chat-ui/widgets'

// When Event with loading status
function SearchDocumentsEvent() {
  return (
    <ChatEvent
      event={{
        title: 'Searching documents',
        description: 'Searching documents for machine learning',
        status: 'pending',
      }}
    />
  )
}

// When Event with success status
function SearchDocumentsResult() {
  return (
    <ChatEvent
      event={{
        title: 'Searching documents',
        description: 'Searching documents for machine learning',
        status: 'success',
        data: 'Document content...',
      }}
    />
  )
}
```

### SuggestedQuestions

Interactive follow-up question suggestions.

```tsx
import { SuggestedQuestions } from '@llamaindex/chat-ui/widgets'

function QuestionSuggestions({ regenerate, requestData }) {
  return (
    <SuggestedQuestions
      questions={[
        'Can you explain this in more detail?',
        'What are the practical applications?',
        'How does this compare to other approaches?',
      ]}
      regenerate={regenerate}
      requestData={requestData}
    />
  )
}
```

### StarterQuestions

Initial conversation starters for empty chat states.

```tsx
import { StarterQuestions } from '@llamaindex/chat-ui/widgets'

const starterQuestions = [
  'How can I improve my code?',
  'Explain machine learning concepts',
  'Help me debug this error',
  'What are best practices for React?',
]

function ChatStarters() {
  return (
    <StarterQuestions
      questions={starterQuestions}
      onQuestionSelect={handleQuestionSelect}
    />
  )
}
```

### FileUploader

Drag-and-drop file upload with validation.

```tsx
import { FileUploader } from '@llamaindex/chat-ui/widgets'

function UploadArea({ onFilesSelected }) {
  return (
    <FileUploader
      accept={{
        'image/*': ['.png', '.jpg', '.jpeg'],
        'application/pdf': ['.pdf'],
        'text/*': ['.txt', '.md'],
      }}
      maxSize={10 * 1024 * 1024} // 10MB
      onFiles={onFilesSelected}
      multiple={true}
    >
      <div className="border-2 border-dashed p-8 text-center">
        <p>Drag files here or click to upload</p>
      </div>
    </FileUploader>
  )
}
```

**Features:**

- **Drag & Drop** - Intuitive file selection
- **File Validation** - Type and size checking
- **Multiple Files** - Batch upload support
- **Progress Tracking** - Upload progress display
- **Error Handling** - Validation error messages

### ImagePreview

Image preview with zoom and manipulation.

```tsx
import { ImagePreview } from '@llamaindex/chat-ui/widgets'

function PreviewImage({ src, alt }) {
  return (
    <ImagePreview
      src={src}
      alt={alt}
      className="max-w-md"
      enableZoom={true}
      showControls={true}
    />
  )
}
```

### DocumentInfo

Document metadata display with formatting.

```tsx
import { DocumentInfo } from '@llamaindex/chat-ui/widgets'

function DocInfo({ document }) {
  return (
    <DocumentInfo
      title={document.title}
      author={document.author}
      date={document.date}
      pages={document.pages}
      size={document.size}
    />
  )
}
```

## Citation

Individual citation component with linking.

```tsx
import { Citation } from '@llamaindex/chat-ui/widgets'

function CitationLink({ source, index }) {
  return (
    <Citation
      number={index + 1}
      title={source.title}
      url={source.url}
      metadata={source.metadata}
      onClick={() => openSource(source)}
    />
  )
}
```

## Widget Integration

### Automatic Rendering

Other widgets render based on message parts through dedicated components:

```tsx
import { ChatMessage } from '@llamaindex/chat-ui'

function MessageWithWidgets({ message }) {
  return (
    <ChatMessage message={message}>
      <ChatMessage.Content>
        <ChatMessage.Part.Markdown />
        <ChatMessage.Part.Image /> {/* Renders ChatImage */}
        <ChatMessage.Part.Source /> {/* Renders ChatSources */}
        <ChatMessage.Part.Event /> {/* Renders ChatEvents */}
      </ChatMessage.Content>
    </ChatMessage>
  )
}
```

The `ChatMessage.Part.*` components internally use the parts pattern described in [Parts](./parts.mdx), extracting data with `usePart` and passing it to the respective widgets.

### Manual Widget Usage

Use widgets independently for custom layouts:

```tsx
import {
  Markdown,
  CodeBlock,
  ChatImage,
  SuggestedQuestions,
} from '@llamaindex/chat-ui/widgets'

function CustomMessageLayout({ message }) {
  return (
    <div className="space-y-4">
      <Markdown>{message.content}</Markdown>

      {message.code && <CodeBlock code={message.code} language="python" />}

      {message.imageUrl && (
        <ChatImage src={message.imageUrl} alt="Generated image" />
      )}

      <SuggestedQuestions questions={message.suggestions} />
    </div>
  )
}
```

### Custom Widget Creation

Create custom widgets by following this pattern:

```tsx
type WeatherData = {
  location: string
  temperature: number
  condition: string
  humidity: number
  windSpeed: number
}

export function WeatherWidget({ data }: { data: WeatherData }) {
  return (
    <div className="rounded-lg bg-blue-50 p-4">
      <h3 className="font-semibold">{data.location}</h3>
      <p className="text-2xl">{data.temperature}°C</p>
      <p className="text-sm text-gray-600">{data.condition}</p>
    </div>
  )
}

// Usage example
function App() {
  return (
    <WeatherWidget
      data={{
        location: 'San Francisco',
        temperature: 22,
        condition: 'Partly cloudy',
        humidity: 65,
        windSpeed: 8,
      }}
    />
  )
}
```

## Next Steps

- [Parts](./parts.mdx) - Learn how to create and send parts
- [Artifacts](./artifacts.mdx) - Implement interactive code and document artifacts
- [Hooks](./hooks.mdx) - Understand the widget hook system
- [Customization](./customization.mdx) - Style and customize widget appearance
